package com.gaoxk.redisdemo;

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;


@Component
@Scope(value = "prototype")
public class RedisLock {

    @Autowired
    private RedisTemplate redisTemplate;

    //@Autowired
    private RedissonClient redissonClient;

    @Value("${spring.redis.host}")
    private String redishost;

    @Value("${spring.redis.port}")
    private String redisport;

    @Value("${spring.redis.password}")
    private String redispassword;





    private static final Logger LOG = LoggerFactory.getLogger(RedisLock.class);
    //默认的database
    private int num =0;
    //命令模式设置分布式锁
    //SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
    //EX second：设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。
    //PX millisecond：设置键的过期时间为毫秒。SET key value PX millisecond 效果等同于 PSETEX key millisecondvalue 。
    //NX：只在键不存在时，才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
    //XX：只在键已经存在时，才对键进行设置操作。
    //例如：SET name www.biancheng.net EX 60 NX

    public boolean lock(int index,String key, String value, long expireTime) {
        LettuceConnectionFactory connectionFactory = (LettuceConnectionFactory) redisTemplate.getConnectionFactory();
        LOG.info("the databse of before lock is:"+connectionFactory.getDatabase());
        if (connectionFactory != null && index != (num =connectionFactory.getDatabase())) {
            connectionFactory.setDatabase(index);
            this.redisTemplate.setConnectionFactory(connectionFactory);
            connectionFactory.resetConnection();
            connectionFactory.afterPropertiesSet();
        }
        LOG.info("the databse of after lock is:"+connectionFactory.getDatabase());
        //expireTime为锁的过时时间毫秒 ，因为是毫秒，最后面的参数为TimeUnit.MILLISECONDS
        Boolean success = redisTemplate.opsForValue().setIfAbsent(key, value, expireTime, TimeUnit.MILLISECONDS);
        return success != null && success;
    }

    public void unlock(int index,String key, String value) {
        LettuceConnectionFactory connectionFactory = (LettuceConnectionFactory) redisTemplate.getConnectionFactory();
        LOG.info("the databse of before unlock is:"+connectionFactory.getDatabase());
        if (connectionFactory != null && index != connectionFactory.getDatabase()) {
            connectionFactory.setDatabase(index);
            this.redisTemplate.setConnectionFactory(connectionFactory);
            connectionFactory.resetConnection();
            connectionFactory.afterPropertiesSet();
        }
        LOG.info("the databse of after unlock is:"+connectionFactory.getDatabase());
        String currentValue = (String)redisTemplate.opsForValue().get(key);
        if (currentValue != null && currentValue.equals(value)) {
            redisTemplate.delete(key);
        }
    }



    public boolean redissonlock(String key, long expireTime) {

        RLock lock = redissonClient.getLock(key);
        try {
            return lock.tryLock(expireTime, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
    }

    public void redissonunlock(String key) {



        RLock lock = redissonClient.getLock(key);
        if (lock.isLocked()) {
            lock.unlock();
        }
    }
    public RedissonClient getRedissonClient( String ip,String port,String password,int database){
        Config config = new Config();
        String redishost1 ="";
        String redisport1 = "";
        String redispassword1 ="";
        if(ip != null && !"".equals(ip)){
            redishost1 = ip;
        }else {
            redishost1 = redishost;
        }
        if(port != null && !"".equals(port)){
            redisport1 = port;
        }else {
            redisport1 = redisport;
        }
        if(password != null && !"".equals(password)){
            redisport1 = password;
        }else {
            redispassword1 = redispassword;
        }
        config.useSingleServer()
                .setAddress("redis://" + redishost1 + ":" + redisport1)
                .setPassword(redispassword1).setDatabase(database);
        RedissonClient redissonClient1 = Redisson.create(config);

        //————————————————
//
//        版权声明：本文为博主原创文章，遵循 CC 4.0 BY-SA 版权协议，转载请附上原文出处链接和本声明。
//
//        原文链接：https://blog.csdn.net/heromps/article/details/141526627
        return redissonClient1;
    }

    public boolean redissondatabaselock(RedissonClient redissonClient1,String key, long expireTime) {



        RLock lock = redissonClient1.getLock(key);
        try {
            return lock.tryLock(expireTime, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
    }

    public void redissondatabaseunlock(RedissonClient redissonClient1,String key) {

        RLock lock = redissonClient1.getLock(key);
        if (lock.isLocked()) {
            lock.unlock();
        }
    }

}
